********************************************************************************
* Caverns of Freitag, by David Shapiro *
* Copyright 1982 *
* *
* Disassembly of "GRAPHIX II". *
********************************************************************************
* The various subroutines are invoked from CF (Applesoft) by way of AMPER, and *
* from CF.OBJ. *
********************************************************************************
* Disassembly by Andy McFadden, using 6502bench SourceGen v1.5. *
* Last updated 2020/01/26 *
********************************************************************************
ARG_DIST .eq $19 ;LINESET distance
ARG_DRAW_MODE .eq $1c ;0=draw, 1=erase, 2=invert
ARG_ITEM_INDEX .eq $1e ;LINESET/CHARSET item index
ARG_COLOR .eq $1f ;0=green, 1=orange, 2=purple, 3=blue
ARG_EXT_PTR .eq $e8 {addr/2} ;pointer to external data
ARG_X0 .eq $f9 {addr/2} ;X coord #0 (0-255 or 0-139)
ARG_Y0 .eq $fb ;Y coord #0 (0-191)
ARG_X1 .eq $fc {addr/2} ;X coord #1 (0-255 or 0-139)
ARG_Y1 .eq $fe ;Y coord #1 (0-191)
ARG_FF .eq $ff ;shape fill flag -or- CLR color
HIRES_PAGE_1 .eq $2000 {addr/8192}
TXTCLR .eq $c050 ;RW display graphics
TXTSET .eq $c051 ;RW display text
MIXCLR .eq $c052 ;RW display full screen
MIXSET .eq $c053 ;RW display split screen
TXTPAGE1 .eq $c054 ;RW display page 1
TXTPAGE2 .eq $c055 ;RW display page 2 (or read/write aux mem)
HIRES .eq $c057 ;RW display hi-res graphics
MON_BELL1 .eq $fbdd ;sound bell regardless of output device
.org $0800
0800: 4c 60 08 DOT jmp HandleDOT
0803: 4c 73 08 jmp HandleDOT_1
0806: 4c ac 08 CHKDOT jmp HandleCHKDOT
0809: 4c d0 08 LINE jmp HandleLINE
080c: 4c 6b 0a LINESET jmp HandleLINESET ;used for wizard Zap attack
080f: 4c 29 0c CLR jmp HandleCLR
0812: 4c c0 0c SCFLIP jmp HandleSCFLIP
0815: 4c ea 0d HISCROLL jmp HandleHISCROLL
0818: 4c 1c 0e BOX jmp HandleBOX
081b: 4c db 0e SWITCHC jmp HandleSWITCHC
081e: 4c f3 0e CHARSET jmp HandleCHARSET ;line 14000 (arrow animation) and 15000 (hit)
0821: 4c 96 0f BDRW jmp HandleBDRW ;draws tiles for mode 1 display
0824: 4c f3 0f CIRCLE jmp HandleCIRCLE
0827: 4c 78 11 PENGUIN jmp HandlePENGUIN
082a: 4c 8a 11 CDOT jmp HandleCDOT
082d: 4c 9d 11 jmp HandleCDOT_1
0830: 4c e7 11 CLINE jmp HandleCLINE
0833: 4c 19 13 CBOX jmp HandleCBOX
0836: 4c 9f 13 CCHARSET jmp HandleCCHARSET
********************************************************************************
* Handle HIRES *
* *
* Enable hi-res graphics. Does not touch mixed-mode flag. *
********************************************************************************
0839: 2c 57 c0 HIRES_ bit HIRES
083c: 2c 50 c0 bit TXTCLR
083f: 60 rts
********************************************************************************
* Handle HROFF *
* *
* Switches to text mode. *
********************************************************************************
0840: 2c 51 c0 HROFF bit TXTSET
0843: 60 rts
********************************************************************************
* Handle WINDOW *
* *
* Enable mixed mode (4 lines of text at bottom). *
********************************************************************************
0844: 2c 53 c0 WINDOW bit MIXSET
0847: 60 rts
********************************************************************************
* Handle WNDOFF *
* *
* Disable mixed mode (full-screen graphics). *
********************************************************************************
0848: 2c 52 c0 WNDOFF bit MIXCLR
084b: 60 rts
********************************************************************************
* Handle DRWPG1 *
* *
* Select hi-res page 1 for drawing. *
********************************************************************************
084c: a9 20 DRWPG1 lda #$20
084e: 8d 85 14 sta hpage
0851: 60 rts
********************************************************************************
* Handle DRWPG2 *
* *
* Select hi-res page 2 for drawing. *
********************************************************************************
0852: a9 40 DRWPG2 lda #$40
0854: 8d 85 14 sta hpage
0857: 60 rts
********************************************************************************
* Handle DISPPG1 *
* *
* Set display to page 1. *
********************************************************************************
0858: 2c 54 c0 DISPPG1 bit TXTPAGE1
085b: 60 rts
********************************************************************************
* Handle DISPPG2 *
* *
* Set display to page 2. *
********************************************************************************
085c: 2c 55 c0 DISPPG2 bit TXTPAGE2
085f: 60 rts
********************************************************************************
* Handle DOT,x0,y0,drawMode *
* *
* On entry: *
* $F9/FA/FB: x0,y0 *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
********************************************************************************
• Clear variables
]hptr .var $06 {addr/2}
0860: a4 fb HandleDOT ldy ARG_Y0 ;range check Y coord
0862: c9 c0 cmp #192 ;off end of screen?
0864: b0 3b bcs :Done ;yup, bail
0866: b9 b6 17 lda hr_addr_lo,y
0869: 85 06 sta ]hptr
086b: b9 76 18 lda hr_addr_hi,y
086e: 0d 85 14 ora hpage
0871: 85 07 sta ]hptr+1
; Call here if the Y coordinate hasn't changed since the previous call.
0873: a6 fa HandleDOT_1 ldx ARG_X0+1 ;high byte of X coord is zero?
0875: f0 14 beq L088B ;yup, keep going
0877: a6 f9 ldx ARG_X0
0879: e0 18 cpx #24 ;range check X coord (280 - 256 = 24)
087b: b0 24 bcs :Done
087d: a4 fa ldy ARG_X0+1 ;it's not zero; is it one?
087f: 88 dey
0880: d0 1f bne :Done
0882: bd 36 1a lda div7_hi,x
0885: a8 tay
0886: bd 4e 1b lda mod7_hi,x
0889: d0 09 bne :Cont ;(always)
088b: a6 f9 L088B ldx ARG_X0
088d: bd 36 19 lda div7_lo,x
0890: a8 tay
0891: bd 4e 1a lda mod7_lo,x
0894: a6 1c :Cont ldx ARG_DRAW_MODE ;draw mode flag
0896: f0 0a beq L08A2 ;=0, use ORA ("draw")
0898: ca dex
0899: d0 0c bne L08A7 ;=2, use EOR ("invert")
089b: 49 7f eor #$7f ;=1, invert and AND ("erase")
089d: 31 06 and (]hptr),y
089f: 91 06 sta (]hptr),y
08a1: 60 :Done rts
08a2: 11 06 L08A2 ora (]hptr),y
08a4: 91 06 sta (]hptr),y
08a6: 60 rts
08a7: 51 06 L08A7 eor (]hptr),y
08a9: 91 06 sta (]hptr),y
08ab: 60 rts
********************************************************************************
* Handle CHKDOT,X0,X0 *
* *
* On entry: *
* $F9/FA/FB: x0,y0 (0-279,0-191) *
* *
* On exit: *
* $FF: $00 if pixels is clear, $01 if pixel is set *
* *
* NOTE: behaves incorrectly X values >= 256. *
* NOTE: if SWITCHC has been called, this will incorrectly report a set pixel *
* if the screen byte is $80 (black1). *
********************************************************************************
]result .var $ff {addr/1}
08ac: a4 fb HandleCHKDOT ldy ARG_Y0 ;set up hi-res address
08ae: b9 b6 17 lda hr_addr_lo,y
08b1: 85 06 sta ]hptr
08b3: b9 76 18 lda hr_addr_hi,y
08b6: 0d 85 14 ora hpage
08b9: 85 07 sta ]hptr+1
08bb: a6 f9 ldx ARG_X0 ;get X offset; note we ignore high byte
08bd: bd 36 19 lda div7_lo,x
08c0: a8 tay
08c1: bd 4e 1a lda mod7_lo,x ;get bit pattern
08c4: 31 06 and (]hptr),y
08c6: d0 03 bne :PixelSet
08c8: 85 ff sta ]result
08ca: 60 rts
08cb: a9 01 :PixelSet lda #$01
08cd: 85 ff sta ]result
08cf: 60 rts
********************************************************************************
* Handle LINE,X0,Y0,X1,Y1,drawMode *
* *
* On entry: *
* $F9/FA/FB: x0,y0 *
* $FC/FD/FE: x1,y1 *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
* *
* On exit: *
* $F9/FA/FB holds 2nd coordinate (so you can chain calls) *
********************************************************************************
• Clear variables
]move_dir .var $08 {addr/1} ;$01 or $ff
]move_dir_hi .var $09 {addr/1}
]tmp_xl .var $19 {addr/1}
]tmp_xh .var $1a {addr/1}
]count .var $1b {addr/1}
]delta_xl .var $1e {addr/1}
]delta_xh .var $1f {addr/1}
]delta_y .var $ff {addr/1}
08d0: a5 fc HandleLINE lda ARG_X1 ;save X1,Y1; this will be restored to X0,Y0 at the end
08d2: 8d 56 14 sta saved_xlo
08d5: a5 fd lda ARG_X1+1
08d7: 8d 57 14 sta saved_xhi
08da: a5 fe lda ARG_Y1
08dc: 8d 58 14 sta saved_y
08df: a5 1f lda ]delta_xh ;save $1F; will be restored before exit
08e1: 8d 69 14 sta saved_1f
08e4: a5 fb lda ARG_Y0 ;compute deltaY
08e6: 38 sec
08e7: e5 fe sbc ARG_Y1
08e9: b0 05 bcs L08F0 ;still positive, good
08eb: a5 fe lda ARG_Y1 ;subtract the other way
08ed: 38 sec
08ee: e5 fb sbc ARG_Y0
08f0: 85 ff L08F0 sta ]delta_y ;FF=deltaY
08f2: a5 fc :ComputeDeltaX lda ARG_X1 ;compute deltaX
08f4: 38 sec
08f5: e5 f9 sbc ARG_X0
08f7: 85 1e sta ]delta_xl ;1E=deltaX low
08f9: a5 fd lda ARG_X1+1 ;now do the high part
08fb: e5 fa sbc ARG_X0+1
08fd: 10 06 bpl L0905 ;positive, good
08ff: 20 52 0a jsr SwapCoords ;flip so we're always X0 < X1
0902: 4c f2 08 jmp :ComputeDeltaX ;redo the delta X computation
0905: 85 1f L0905 sta ]delta_xh ;1F=deltaX hi
0907: d0 6b bne HorizDom ;if deltaX high is nonzero, we're primarily horizontal
0909: a5 1e lda ]delta_xl ;is this a vertical line?
090b: f0 0e beq VerticalOrPoint ;yup
090d: a5 ff lda ]delta_y ;is this a horizontal line?
090f: f0 2f beq HorizontalLine ;yup
0911: a5 1e lda ]delta_xl ;compare deltaX to deltaY
0913: 38 sec
0914: e5 ff sbc ]delta_y
0916: b0 5c bcs HorizDom
0918: 4c ec 09 jmp VertDom
091b: a5 ff VerticalOrPoint lda ]delta_y ;just a point?
091d: d0 06 bne VerticalLine ;nope
091f: 20 60 08 jsr HandleDOT ;yes, plot it
0922: 4c 3d 0a jmp RestoreXY
0925: a5 fe VerticalLine lda ARG_Y1 ;ensure Y1 > Y0
0927: 38 sec
0928: e5 fb sbc ARG_Y0
092a: b0 03 bcs :NoSwap
092c: 20 52 0a jsr SwapCoords
092f: 20 60 08 :NoSwap jsr HandleDOT ;draw a dot at X0,Y0
0932: e6 fb :DrawLoop inc ARG_Y0 ;move down
0934: 20 60 08 jsr HandleDOT ;draw a dot at X0,Y0
0937: a5 fb lda ARG_Y0
0939: c5 fe cmp ARG_Y1 ;done yet?
093b: d0 f5 bne :DrawLoop ;no, keep going
093d: 4c 3d 0a jmp RestoreXY
0940: 20 60 08 HorizontalLine jsr HandleDOT ;draw a dot at X0,Y0
0943: e6 f9 HorizDrawLoop inc ARG_X0 ;move right
0945: d0 02 bne :NoInc
0947: e6 fa inc ARG_X0+1
0949: 20 73 08 :NoInc jsr HandleDOT_1 ;draw a dot at X0,Y0, skipping Y addr setup
094c: a5 f9 lda ARG_X0 ;check if we're done
094e: c5 fc cmp ARG_X1
0950: d0 f1 bne HorizDrawLoop
0952: a5 fa lda ARG_X0+1
0954: c5 fd cmp ARG_X1+1
0956: d0 eb bne HorizDrawLoop
0958: 4c 3d 0a jmp RestoreXY
; Neither dominant - diagonal line.
095b: e6 f9 DiagonalDom inc ARG_X0 ;always move right
095d: d0 02 bne :NoInc
095f: e6 fa inc ARG_X0+1
0961: a5 fb :NoInc lda ARG_Y0 ;update Y coord
0963: 18 clc
0964: 65 08 adc ]move_dir
0966: 85 fb sta ARG_Y0
0968: 20 60 08 jsr HandleDOT ;draw dot
096b: a5 fb lda ARG_Y0
096d: c5 fe cmp ARG_Y1 ;done yet?
096f: d0 ea bne DiagonalDom ;no, keep going
0971: 4c 3d 0a jmp RestoreXY
; Horizontally-dominant line.
0974: 20 60 08 HorizDom jsr HandleDOT ;draw a point at X0,Y0
0977: a5 1e lda ]delta_xl ;check for purely-horizontal line
0979: 85 19 sta ]tmp_xl
097b: a5 1f lda ]delta_xh
097d: 85 1a sta ]tmp_xh
097f: a5 fe lda ARG_Y1
0981: 38 sec
0982: e5 fb sbc ARG_Y0
0984: f0 bd beq HorizDrawLoop ;go be horizontal
0986: 90 06 bcc :Upward ;line moves up
0988: a9 01 lda #$01 ;line moves downward
098a: 85 08 sta ]move_dir
098c: d0 04 bne L0992 ;(always)
098e: a9 ff :Upward lda #$ff
0990: 85 08 sta ]move_dir
0992: a5 1f L0992 lda ]delta_xh ;check for 1:1 diagonal
0994: d0 06 bne L099C
0996: a5 1e lda ]delta_xl
0998: c5 ff cmp ]delta_y
099a: f0 bf beq DiagonalDom
099c: a5 1e L099C lda ]delta_xl ;set initial delta
099e: 38 sec
099f: e5 ff sbc ]delta_y
09a1: 85 1e sta ]delta_xl
09a3: b0 02 bcs :HorizDomLoop
09a5: c6 1f dec ]delta_xh
; Core of horizontally-dominant line draw.
09a7: a5 1e :HorizDomLoop lda ]delta_xl ;do the delta adjustment to see if we need to move
09a9: 38 sec ; vertically at this step
09aa: e5 ff sbc ]delta_y
09ac: 85 1e sta ]delta_xl
09ae: b0 04 bcs L09B4
09b0: c6 1f dec ]delta_xh
09b2: 30 0c bmi :MoveVert ;yup, need to move vertically
09b4: e6 f9 L09B4 inc ARG_X0 ;move right every time
09b6: d0 02 bne :NoInc
09b8: e6 fa inc ARG_X0+1
09ba: 20 73 08 :NoInc jsr HandleDOT_1 ;draw dot without updating Y addr
09bd: 4c dd 09 jmp L09DD
09c0: a5 1e :MoveVert lda ]delta_xl ;update deltas
09c2: 18 clc
09c3: 65 19 adc ]tmp_xl
09c5: 85 1e sta ]delta_xl
09c7: a5 1f lda ]delta_xh
09c9: 65 1a adc ]tmp_xh
09cb: 85 1f sta ]delta_xh
09cd: a5 fb lda ARG_Y0 ;advance Y coordinate
09cf: 18 clc
09d0: 65 08 adc ]move_dir
09d2: 85 fb sta ARG_Y0
09d4: e6 f9 inc ARG_X0 ;move right every time
09d6: d0 02 bne :NoInc
09d8: e6 fa inc ARG_X0+1
09da: 20 60 08 :NoInc jsr HandleDOT ;draw dot after updating Y addr
09dd: a5 f9 L09DD lda ARG_X0 ;check if we're done
09df: c5 fc cmp ARG_X1
09e1: d0 c4 bne :HorizDomLoop
09e3: a5 fa lda ARG_X0+1
09e5: c5 fd cmp ARG_X1+1
09e7: d0 be bne :HorizDomLoop
09e9: 4c 3d 0a jmp RestoreXY
; Vertically-dominant line.
09ec: a5 fe VertDom lda ARG_Y1 ;make sure Y1 > Y0
09ee: 38 sec
09ef: e5 fb sbc ARG_Y0
09f1: b0 0b bcs :MoveRight
09f3: 20 52 0a jsr SwapCoords
09f6: a9 ff lda #$ff ;move to the left
09f8: 85 08 sta ]move_dir
09fa: 85 09 sta ]move_dir_hi
09fc: 30 08 bmi :MoveSet
09fe: a9 01 :MoveRight lda #$01 ;move to the right
0a00: 85 08 sta ]move_dir
0a02: a9 00 lda #$00
0a04: 85 09 sta ]move_dir_hi
0a06: a5 ff :MoveSet lda ]delta_y ;configure deltas
0a08: 85 1b sta ]count
0a0a: 85 19 sta ]tmp_xl
0a0c: 38 sec
0a0d: e5 1e sbc ]delta_xl
0a0f: 85 ff sta ]delta_y
0a11: 20 60 08 jsr HandleDOT ;draw dot at X0,Y0
0a14: a5 ff :VertDomLoop lda ]delta_y ;update delta, see if it's time to update X
0a16: 38 sec
0a17: e5 1e sbc ]delta_xl
0a19: 85 ff sta ]delta_y
0a1b: b0 14 bcs :NoXMove
0a1d: a5 ff lda ]delta_y
0a1f: 18 clc
0a20: 65 19 adc ]tmp_xl
0a22: 85 ff sta ]delta_y
0a24: a5 f9 lda ARG_X0 ;update X
0a26: 18 clc
0a27: 65 08 adc ]move_dir
0a29: 85 f9 sta ARG_X0
0a2b: a5 fa lda ARG_X0+1
0a2d: 65 09 adc ]move_dir_hi
0a2f: 85 fa sta ARG_X0+1
0a31: e6 fb :NoXMove inc ARG_Y0 ;Y always moves down
0a33: 20 60 08 jsr HandleDOT ;draw dot at X0,Y0
0a36: c6 1b dec ]count ;done yet?
0a38: d0 da bne :VertDomLoop ;nope, keep going
0a3a: 4c 3d 0a jmp RestoreXY
0a3d: ad 56 14 RestoreXY lda saved_xlo
0a40: 85 f9 sta ARG_X0
0a42: ad 57 14 lda saved_xhi
0a45: 85 fa sta ARG_X0+1
0a47: ad 58 14 lda saved_y
0a4a: 85 fb sta ARG_Y0
0a4c: ad 69 14 lda saved_1f
0a4f: 85 1f sta ]delta_xh
0a51: 60 rts
; Swap X0,Y0 with X1,Y1 (F9/FA/FB <-> FC/FD/FE).
• Clear variables
0a52: a5 f9 SwapCoords lda ARG_X0
0a54: a6 fc ldx ARG_X1
0a56: 86 f9 stx ARG_X0
0a58: 85 fc sta ARG_X1
0a5a: a5 fa lda ARG_X0+1
0a5c: a6 fd ldx ARG_X1+1
0a5e: 86 fa stx ARG_X0+1
0a60: 85 fd sta ARG_X1+1
0a62: a5 fb lda ARG_Y0
0a64: a4 fe ldy ARG_Y1
0a66: 84 fb sty ARG_Y0
0a68: 85 fe sta ARG_Y1
0a6a: 60 rts
********************************************************************************
* Handle LINESET,colorIndex,x0,y0,dataPtr,index,dist,angle,drawMode *
* *
* Draws a series of lines from an array of vectors. *
* *
* On entry: *
* $1F: colorIndex (0-3 for color, 4 for white) *
* $F9/FA/FB: x0,y0 *
* $E8/E9: pointer to coord data (e.g. LBOLT @ 816/$330) *
* $1E: index *
* $19: distance in tiles, x16 (will be 16-96) *
* $1D: angle (0-255) *
* $1C: drawMode *
* *
* For LBOLT, the four entries correspond to the primary direction (0=left, *
* 1=up, 2=right, 3=down). *
********************************************************************************
• Clear variables
]angle .var $1d {addr/1}
]entry_index .var $1e {addr/1} ;0-3
]ptr .var $20 {addr/2}
]data_index .var $22 {addr/1}
]dist16 .var $23 {addr/1} ;distance, in tiles, x16
0a6b: a2 0a HandleLINESET ldx #$0a ;save $20-2a so we can use it
0a6d: b5 20 :SaveLoop lda ]ptr,x
0a6f: 9d 5b 14 sta scratch0,x
0a72: ca dex
0a73: 10 f8 bpl :SaveLoop
0a75: a5 19 lda ARG_DIST
0a77: 85 23 sta ]dist16
0a79: a5 e8 lda ARG_EXT_PTR
0a7b: 85 20 sta ]ptr
0a7d: a5 e9 lda ARG_EXT_PTR+1
0a7f: 85 21 sta ]ptr+1
0a81: a5 1e lda ]entry_index ;double index, use as file offset
0a83: 0a asl A
0a84: a8 tay
0a85: b1 20 lda (]ptr),y ;offset lo
0a87: 85 19 sta ARG_DIST
0a89: c8 iny
0a8a: b1 20 lda (]ptr),y ;offset hi
0a8c: aa tax
0a8d: a5 19 lda ARG_DIST ;update ptr
0a8f: 18 clc
0a90: 65 20 adc ]ptr
0a92: 85 20 sta ]ptr
0a94: 8a txa
0a95: 65 21 adc ]ptr+1
0a97: 85 21 sta ]ptr+1
;
0a99: a9 00 lda #$00
0a9b: 85 22 sta ]data_index
0a9d: a4 22 PointLoop ldy ]data_index
0a9f: b1 20 lda (]ptr),y ;get the X coord
0aa1: 85 fc sta ARG_X1
0aa3: 20 2e 0b jsr AdvancePtr ;advance to next byte
0aa6: b1 20 lda (]ptr),y ;get the Y coord
0aa8: 85 fe sta ARG_Y1
0aaa: d0 0f bne :NotZero
0aac: c5 fc cmp ARG_X1 ;Y was zero, was X as well?
0aae: d0 0b bne :NotZero
; Found $00/$00, end of list reached. Restore DP we trampled.
0ab0: a2 0a ldx #$0a
0ab2: bd 5b 14 :RestoreLoop lda scratch0,x
0ab5: 95 20 sta ]ptr,x
0ab7: ca dex
0ab8: 10 f8 bpl :RestoreLoop
0aba: 60 rts
0abb: 20 2e 0b :NotZero jsr AdvancePtr ;advance to next byte
0abe: 84 22 sty ]data_index ;save this off
0ac0: a5 23 lda ]dist16 ;check the distance
0ac2: c9 10 cmp #16 ;1 tile?
0ac4: f0 03 beq :OneTile
0ac6: 20 34 0b jsr ScaleVector
0ac9: a5 1d :OneTile lda ]angle
0acb: f0 03 beq :NoAngle
0acd: 20 b5 0b jsr RotateByAngle
0ad0: a9 00 :NoAngle lda #$00
0ad2: a6 fc ldx ARG_X1 ;check X1 sign
0ad4: 10 02 bpl :XNeg
0ad6: a9 ff lda #$ff
0ad8: 85 fd :XNeg sta ARG_X1+1 ;sign-extend X1
0ada: a5 fc lda ARG_X1 ;set X1 = X1 + X0
0adc: 18 clc
0add: 65 f9 adc ARG_X0
0adf: 85 fc sta ARG_X1
0ae1: a5 fd lda ARG_X1+1
0ae3: 65 fa adc ARG_X0+1
0ae5: 85 fd sta ARG_X1+1
0ae7: a5 fe lda ARG_Y1 ;set Y1 = Y1 + Y0
0ae9: 18 clc
0aea: 65 fb adc ARG_Y0
0aec: 85 fe sta ARG_Y1
0aee: a4 22 ldy ]data_index
0af0: b1 20 lda (]ptr),y ;get next byte
0af2: d0 03 bne :DoDraw ;nonzero, draw a line
0af4: 4c 1a 0b jmp :MoveOnly ;zero, just move
0af7: 20 2e 0b :DoDraw jsr AdvancePtr
0afa: 84 22 sty ]data_index
0afc: a5 1f lda ARG_COLOR
0afe: c9 04 cmp #$04 ;green/purple/blue/orange?
0b00: 90 06 bcc :DrawColor ;yes
0b02: 20 d0 08 jsr HandleLINE ;no, white; draw solid line
0b05: 4c 9d 0a jmp PointLoop
0b08: 46 fa :DrawColor lsr ARG_X0+1 ;divide X coord by 2 for color mode
0b0a: 66 f9 ror ARG_X0
0b0c: 46 fd lsr ARG_X1+1
0b0e: 66 fc ror ARG_X1
0b10: 20 e7 11 jsr HandleCLINE ;draw line
0b13: 06 f9 asl ARG_X0 ;restore X0
0b15: 26 fa rol ARG_X0+1
0b17: 4c 9d 0a jmp PointLoop
0b1a: 20 2e 0b :MoveOnly jsr AdvancePtr ;move to start of next entry
0b1d: 84 22 sty ]data_index
0b1f: a5 fc lda ARG_X1 ;set X0=X1 (this is done by the line-drawing code)
0b21: 85 f9 sta ARG_X0
0b23: a5 fd lda ARG_X1+1
0b25: 85 fa sta ARG_X0+1
0b27: a5 fe lda ARG_Y1
0b29: 85 fb sta ARG_Y0
0b2b: 4c 9d 0a jmp PointLoop
; Increment 16-bit value in Y-reg and $21.
0b2e: c8 AdvancePtr iny
0b2f: d0 02 bne :NoInc
0b31: e6 21 inc ]ptr+1
0b33: 60 :NoInc rts
; Scale the vector in X1/Y1 (part of LINESET).
;
; On entry:
; Y-reg: dist * 16
; X1/Y1: vector to scale
;
; On exit:
; Y-reg: (unchanged)
; X1/Y1 updated
0b34: a8 ScaleVector tay ;put dist in Y-reg
0b35: a5 fc lda ARG_X1
0b37: 20 44 0b jsr ScaleVectorPart
0b3a: 85 fc sta ARG_X1
0b3c: a5 fe lda ARG_Y1
0b3e: 20 44 0b jsr ScaleVectorPart
0b41: 85 fe sta ARG_Y1
0b43: 60 rts
; Scale the delta value in A-reg by the value in Y-reg.
;
; On exit:
; A-reg: scaled value
; Y-reg: unchanged
• Clear variables
]saved_val .var $08 {addr/1}
]tmpval .var $19 {addr/2}
]xresult .var $1e {addr/1}
]mult_bit .var $25 {addr/1}
]result_val .var $26 {addr/2}
]xsign .var $28 {addr/1}
]ysign .var $29 {addr/1}
]ytemp .var $ff {addr/1}
0b44: 85 08 ScaleVectorPart sta ]saved_val
0b46: 85 1a sta ]tmpval+1 ;put in high byte of 16-bit word
0b48: a9 00 lda #$00
0b4a: 85 19 sta ]tmpval
0b4c: 85 26 sta ]result_val
0b4e: 85 27 sta ]result_val+1
0b50: 46 1a lsr ]tmpval+1 ;divide by 16
0b52: 66 19 ror ]tmpval
0b54: 46 1a lsr ]tmpval+1
0b56: 66 19 ror ]tmpval
0b58: 46 1a lsr ]tmpval+1
0b5a: 66 19 ror ]tmpval
0b5c: 46 1a lsr ]tmpval+1
0b5e: 66 19 ror ]tmpval
0b60: a5 08 lda ]saved_val ;is original negative?
0b62: 10 06 bpl :OrigPos
0b64: a5 1a lda ]tmpval+1 ;yes, sign-extend
0b66: 09 f0 ora #$f0
0b68: 85 1a sta ]tmpval+1
0b6a: a9 01 :OrigPos lda #$01 ;init multiplier
0b6c: 85 25 sta ]mult_bit
0b6e: 98 :MultLoop tya
0b6f: 25 25 and ]mult_bit ;add or shift?
0b71: f0 0d beq :Shift
0b73: a5 19 lda ]tmpval ;add to result
0b75: 18 clc
0b76: 65 26 adc ]result_val
0b78: 85 26 sta ]result_val
0b7a: a5 1a lda ]tmpval+1
0b7c: 65 27 adc ]result_val+1
0b7e: 85 27 sta ]result_val+1
0b80: 06 19 :Shift asl ]tmpval ;multiply by 2
0b82: 26 1a rol ]tmpval+1
0b84: 06 25 asl ]mult_bit
0b86: d0 e6 bne :MultLoop ;repeat 8x
0b88: a5 08 lda ]saved_val
0b8a: 10 09 bpl :Pos
0b8c: a5 26 lda ]result_val
0b8e: 30 0b bmi :Pos2
0b90: c6 27 dec ]result_val+1
0b92: 4c 9b 0b jmp :Pos2
0b95: a5 26 :Pos lda ]result_val
0b97: 10 02 bpl :Pos2
0b99: e6 27 inc ]result_val+1
0b9b: a5 27 :Pos2 lda ]result_val+1 ;result in high byte
0b9d: 60 rts
0b9e: 85 08 DoScaleMult sta ]saved_val
0ba0: 85 19 sta ]tmpval
0ba2: a9 00 lda #$00
0ba4: 85 1a sta ]tmpval+1
0ba6: 85 26 sta ]result_val
0ba8: 85 27 sta ]result_val+1
0baa: a5 08 lda ]saved_val ;positive?
0bac: 10 bc bpl :OrigPos
0bae: a9 ff lda #$ff ;no, sign-extend
0bb0: 85 1a sta ]tmpval+1
0bb2: 4c 6a 0b jmp :OrigPos
; Rotates the coordinates by an arbitrary angle. (Not used by CF.)
;
; The angle value is 0-255. 64 rotates 90 degrees clockwise.
;
; On entry:
; A-reg: angle (0-255)
; $FC: X coord (X1)
; $FE: Y coord (Y1)
0bb5: aa RotateByAngle tax ;save arg
0bb6: 4a lsr A ;divide by 64 to get quadrant
0bb7: 4a lsr A
0bb8: 4a lsr A
0bb9: 4a lsr A
0bba: 4a lsr A
0bbb: 4a lsr A ;now 0-3
0bbc: a8 tay
0bbd: b9 6a 14 lda angle_xsign,y ;get $01 or $ff depending on direction
0bc0: 85 28 sta ]xsign
0bc2: b9 6e 14 lda angle_ysign,y
0bc5: 85 29 sta ]ysign
; XC = X * cos(theta) - Y * sin(theta)
0bc7: 8a txa ;get arg
0bc8: 29 7f and #$7f ;strip the hi bit
0bca: aa tax
0bcb: bd 36 17 lda angle_cos,x
0bce: a8 tay
0bcf: a5 fc lda ARG_X1
0bd1: 20 9e 0b jsr DoScaleMult
0bd4: a4 29 ldy ]ysign ;should it be positive?
0bd6: 10 05 bpl :XCosPos ;yes
0bd8: 49 ff eor #$ff ;make negative (invert and add one)
0bda: 18 clc
0bdb: 69 01 adc #$01
0bdd: 85 1e :XCosPos sta ]xresult
0bdf: 8a txa
0be0: bd b6 16 lda angle_sin,x
0be3: a8 tay
0be4: a5 fe lda ARG_Y1
0be6: 20 9e 0b jsr DoScaleMult
0be9: a4 28 ldy ]xsign ;should it be positive?
0beb: 30 05 bmi :YSinNeg ;no
0bed: 49 ff eor #$ff ;yes, but we're subtracting, so invert it
0bef: 18 clc
0bf0: 69 01 adc #$01
0bf2: 18 :YSinNeg clc
0bf3: 65 1e adc ]xresult
0bf5: 85 1e sta ]xresult
; YC = Y * cos(theta) + X * sin(theta)
0bf7: 8a txa
0bf8: bd b6 16 lda angle_sin,x
0bfb: a8 tay
0bfc: a5 fc lda ARG_X1
0bfe: 20 9e 0b jsr DoScaleMult
0c01: a4 28 ldy ]xsign ;check sign
0c03: 10 05 bpl :XSinPos
0c05: 49 ff eor #$ff ;should be negative, invert
0c07: 18 clc
0c08: 69 01 adc #$01
0c0a: 85 ff :XSinPos sta ]ytemp
0c0c: 8a txa
0c0d: bd 36 17 lda angle_cos,x
0c10: a8 tay
0c11: a5 fe lda ARG_Y1
0c13: 20 9e 0b jsr DoScaleMult
0c16: a4 29 ldy ]ysign ;check sign
0c18: 10 05 bpl :YCosPos
0c1a: 49 ff eor #$ff ;should be negative, invert
0c1c: 18 clc
0c1d: 69 01 adc #$01
0c1f: 18 :YCosPos clc
0c20: 65 ff adc ]ytemp
0c22: 85 fe sta ARG_Y1
0c24: a5 1e lda ]xresult
0c26: 85 fc sta ARG_X1
0c28: 60 rts
********************************************************************************
* Handle CLR,color *
* *
* On entry: *
* $FF - color index (0-7) *
* *
* The color index matches the Applesoft colors (black0, green, purple, ...). *
********************************************************************************
0c29: a0 5d HandleCLR ldy #93 ;(32 - 1) * 3
; OR the page into the 32 STA statements
0c2b: ae 85 14 ldx hpage
0c2e: 8a :SetLoop txa
0c2f: 19 43 0c ora :_ClearLoop+2,y
0c32: 99 43 0c sta :_ClearLoop+2,y
0c35: 88 dey
0c36: 88 dey
0c37: 88 dey
0c38: 10 f4 bpl :SetLoop
; do the clear
0c3a: a0 00 ldy #$00
0c3c: a6 ff ldx ]ytemp
0c3e: bd 72 14 lda clr_color_table,x
0c41: 99 00 00 :_ClearLoop sta HIRES_PAGE_1-$2000,y ;unroll loop for speed
0c44: 99 00 01 sta HIRES_PAGE_1-$1f00,y
0c47: 99 00 02 sta HIRES_PAGE_1-$1e00,y
0c4a: 99 00 03 sta HIRES_PAGE_1-$1d00,y
0c4d: 99 00 04 sta HIRES_PAGE_1-$1c00,y
0c50: 99 00 05 sta HIRES_PAGE_1-$1b00,y
0c53: 99 00 06 sta HIRES_PAGE_1-$1a00,y
0c56: 99 00 07 sta HIRES_PAGE_1-$1900,y
0c59: 99 00 08 sta HIRES_PAGE_1-$1800,y
0c5c: 99 00 09 sta HIRES_PAGE_1-$1700,y
0c5f: 99 00 0a sta HIRES_PAGE_1-$1600,y
0c62: 99 00 0b sta HIRES_PAGE_1-$1500,y
0c65: 99 00 0c sta HIRES_PAGE_1-$1400,y
0c68: 99 00 0d sta HIRES_PAGE_1-$1300,y
0c6b: 99 00 0e sta HIRES_PAGE_1-$1200,y
0c6e: 99 00 0f sta HIRES_PAGE_1-$1100,y
0c71: 99 00 10 sta HIRES_PAGE_1-$1000,y
0c74: 99 00 11 sta HIRES_PAGE_1-$f00,y
0c77: 99 00 12 sta HIRES_PAGE_1-$e00,y
0c7a: 99 00 13 sta HIRES_PAGE_1-$d00,y
0c7d: 99 00 14 sta HIRES_PAGE_1-$c00,y
0c80: 99 00 15 sta HIRES_PAGE_1-$b00,y
0c83: 99 00 16 sta HIRES_PAGE_1-$a00,y
0c86: 99 00 17 sta HIRES_PAGE_1-$900,y
0c89: 99 00 18 sta HIRES_PAGE_1-$800,y
0c8c: 99 00 19 sta HIRES_PAGE_1-$700,y
0c8f: 99 00 1a sta HIRES_PAGE_1-$600,y
0c92: 99 00 1b sta HIRES_PAGE_1-$500,y
0c95: 99 00 1c sta HIRES_PAGE_1-$400,y
0c98: 99 00 1d sta HIRES_PAGE_1-$300,y
0c9b: 99 00 1e sta HIRES_PAGE_1-$200,y
0c9e: 99 00 1f sta HIRES_PAGE_1-$100,y
0ca1: 8a txa
0ca2: 49 08 eor #$08 ;flip odd/even color index
0ca4: aa tax
0ca5: bd 72 14 lda clr_color_table,x ;get color
0ca8: c8 iny
0ca9: d0 96 bne :_ClearLoop ;loop until done
; reset the STA statements
0cab: a0 5d ldy #$5d
0cad: ad 85 14 lda hpage
0cb0: 49 ff eor #$ff
0cb2: aa tax
0cb3: 8a :ResetLoop txa
0cb4: 39 43 0c and :_ClearLoop+2,y
0cb7: 99 43 0c sta :_ClearLoop+2,y
0cba: 88 dey
0cbb: 88 dey
0cbc: 88 dey
0cbd: 10 f4 bpl :ResetLoop
0cbf: 60 rts
********************************************************************************
* Handle SCFLIP,mode *
* *
* Changes the colors on the hi-res screen by exclusive-ORing every byte with a *
* mask. *
* *
* On entry: *
* $FF: mask (0=$7F, 1=$80, 2=$FF) *
********************************************************************************
• Clear variables
0cc0: a0 e0 HandleSCFLIP ldy #224 ;32 pairs * 7 bytes each
0cc2: ae 85 14 ldx hpage
0cc5: 8a :SetLoop txa
0cc6: 19 e0 0c ora :_FlipInst1,y ;not actually modifying target instruction; last mod
0cc9: 99 e0 0c sta :_FlipInst1,y ; is _FlipInst1+7
0ccc: 8a txa
0ccd: 19 e3 0c ora :_FlipInst2,y
0cd0: 99 e3 0c sta :_FlipInst2,y
0cd3: 88 dey
0cd4: 88 dey
0cd5: 88 dey
0cd6: 88 dey
0cd7: 88 dey
0cd8: 88 dey
0cd9: 88 dey
0cda: d0 e9 bne :SetLoop
0cdc: a0 00 ldy #$00
0cde: a6 ff ldx ARG_FF
0ce0: bd 82 14 :_FlipInst1 lda flip_pattern,x
0ce3: aa :_FlipInst2 tax
0ce4: 8a :FlipLoop txa
0ce5: 59 00 00 eor HIRES_PAGE_1-$2000,y ;unroll loop for speed
0ce8: 99 00 00 sta HIRES_PAGE_1-$2000,y
0ceb: 8a txa
0cec: 59 00 01 eor HIRES_PAGE_1-$1f00,y
0cef: 99 00 01 sta HIRES_PAGE_1-$1f00,y
0cf2: 8a txa
0cf3: 59 00 02 eor HIRES_PAGE_1-$1e00,y
0cf6: 99 00 02 sta HIRES_PAGE_1-$1e00,y
0cf9: 8a txa
0cfa: 59 00 03 eor HIRES_PAGE_1-$1d00,y
0cfd: 99 00 03 sta HIRES_PAGE_1-$1d00,y
0d00: 8a txa
0d01: 59 00 04 eor HIRES_PAGE_1-$1c00,y
0d04: 99 00 04 sta HIRES_PAGE_1-$1c00,y
0d07: 8a txa
0d08: 59 00 05 eor HIRES_PAGE_1-$1b00,y
0d0b: 99 00 05 sta HIRES_PAGE_1-$1b00,y
0d0e: 8a txa
0d0f: 59 00 06 eor HIRES_PAGE_1-$1a00,y
0d12: 99 00 06 sta HIRES_PAGE_1-$1a00,y
0d15: 8a txa
0d16: 59 00 07 eor HIRES_PAGE_1-$1900,y
0d19: 99 00 07 sta HIRES_PAGE_1-$1900,y
0d1c: 8a txa
0d1d: 59 00 08 eor HIRES_PAGE_1-$1800,y
0d20: 99 00 08 sta HIRES_PAGE_1-$1800,y
0d23: 8a txa
0d24: 59 00 09 eor HIRES_PAGE_1-$1700,y
0d27: 99 00 09 sta HIRES_PAGE_1-$1700,y
0d2a: 8a txa
0d2b: 59 00 0a eor HIRES_PAGE_1-$1600,y
0d2e: 99 00 0a sta HIRES_PAGE_1-$1600,y
0d31: 8a txa
0d32: 59 00 0b eor HIRES_PAGE_1-$1500,y
0d35: 99 00 0b sta HIRES_PAGE_1-$1500,y
0d38: 8a txa
0d39: 59 00 0c eor HIRES_PAGE_1-$1400,y
0d3c: 99 00 0c sta HIRES_PAGE_1-$1400,y
0d3f: 8a txa
0d40: 59 00 0d eor HIRES_PAGE_1-$1300,y
0d43: 99 00 0d sta HIRES_PAGE_1-$1300,y
0d46: 8a txa
0d47: 59 00 0e eor HIRES_PAGE_1-$1200,y
0d4a: 99 00 0e sta HIRES_PAGE_1-$1200,y
0d4d: 8a txa
0d4e: 59 00 0f eor HIRES_PAGE_1-$1100,y
0d51: 99 00 0f sta HIRES_PAGE_1-$1100,y
0d54: 8a txa
0d55: 59 00 10 eor HIRES_PAGE_1-$1000,y
0d58: 99 00 10 sta HIRES_PAGE_1-$1000,y
0d5b: 8a txa
0d5c: 59 00 11 eor HIRES_PAGE_1-$f00,y
0d5f: 99 00 11 sta HIRES_PAGE_1-$f00,y
0d62: 8a txa
0d63: 59 00 12 eor HIRES_PAGE_1-$e00,y
0d66: 99 00 12 sta HIRES_PAGE_1-$e00,y
0d69: 8a txa
0d6a: 59 00 13 eor HIRES_PAGE_1-$d00,y
0d6d: 99 00 13 sta HIRES_PAGE_1-$d00,y
0d70: 8a txa
0d71: 59 00 14 eor HIRES_PAGE_1-$c00,y
0d74: 99 00 14 sta HIRES_PAGE_1-$c00,y
0d77: 8a txa
0d78: 59 00 15 eor HIRES_PAGE_1-$b00,y
0d7b: 99 00 15 sta HIRES_PAGE_1-$b00,y
0d7e: 8a txa
0d7f: 59 00 16 eor HIRES_PAGE_1-$a00,y
0d82: 99 00 16 sta HIRES_PAGE_1-$a00,y
0d85: 8a txa
0d86: 59 00 17 eor HIRES_PAGE_1-$900,y
0d89: 99 00 17 sta HIRES_PAGE_1-$900,y
0d8c: 8a txa
0d8d: 59 00 18 eor HIRES_PAGE_1-$800,y
0d90: 99 00 18 sta HIRES_PAGE_1-$800,y
0d93: 8a txa
0d94: 59 00 19 eor HIRES_PAGE_1-$700,y
0d97: 99 00 19 sta HIRES_PAGE_1-$700,y
0d9a: 8a txa
0d9b: 59 00 1a eor HIRES_PAGE_1-$600,y
0d9e: 99 00 1a sta HIRES_PAGE_1-$600,y
0da1: 8a txa
0da2: 59 00 1b eor HIRES_PAGE_1-$500,y
0da5: 99 00 1b sta HIRES_PAGE_1-$500,y
0da8: 8a txa
0da9: 59 00 1c eor HIRES_PAGE_1-$400,y
0dac: 99 00 1c sta HIRES_PAGE_1-$400,y
0daf: 8a txa
0db0: 59 00 1d eor HIRES_PAGE_1-$300,y
0db3: 99 00 1d sta HIRES_PAGE_1-$300,y
0db6: 8a txa
0db7: 59 00 1e eor HIRES_PAGE_1-$200,y
0dba: 99 00 1e sta HIRES_PAGE_1-$200,y
0dbd: 8a txa
0dbe: 59 00 1f eor HIRES_PAGE_1-$100,y
0dc1: 99 00 1f sta HIRES_PAGE_1-$100,y
0dc4: c8 iny
0dc5: f0 03 beq :Done
0dc7: 4c e4 0c jmp :FlipLoop
0dca: a0 e0 :Done ldy #224 ;now strip the hpage out of the instructions
0dcc: ad 85 14 lda hpage ; so it's clean for next time
0dcf: 49 ff eor #$ff
0dd1: aa tax
0dd2: 8a :ResetLoop txa
0dd3: 39 e0 0c and :_FlipInst1,y
0dd6: 99 e0 0c sta :_FlipInst1,y
0dd9: 8a txa
0dda: 39 e3 0c and :_FlipInst2,y
0ddd: 99 e3 0c sta :_FlipInst2,y
0de0: 88 dey
0de1: 88 dey
0de2: 88 dey
0de3: 88 dey
0de4: 88 dey
0de5: 88 dey
0de6: 88 dey
0de7: d0 e9 bne :ResetLoop
0de9: 60 rts
********************************************************************************
* Handle HISCROLL *
* *
* Scrolls the hi-res screen up one line. *
********************************************************************************
• Clear variables
]dst_ptr .var $06 {addr/2}
]src_ptr .var $08 {addr/2}
0dea: a2 00 HandleHISCROLL ldx #$00 ;destination is row 0
0dec: bd b6 17 :RowLoop lda hr_addr_lo,x
0def: 85 06 sta ]dst_ptr
0df1: bd 76 18 lda hr_addr_hi,x
0df4: 0d 85 14 ora hpage
0df7: 85 07 sta ]dst_ptr+1
0df9: e8 inx ;source is row 1
0dfa: bd b6 17 lda hr_addr_lo,x
0dfd: 85 08 sta ]src_ptr
0dff: bd 76 18 lda hr_addr_hi,x
0e02: 85 09 sta ]src_ptr+1
0e04: a0 27 ldy #39 ;40 bytes per line
0e06: b1 08 :ColLoop lda (]src_ptr),y
0e08: 91 06 sta (]dst_ptr),y
0e0a: 88 dey
0e0b: 10 f9 bpl :ColLoop
0e0d: e0 bf cpx #191 ;191 rows
0e0f: d0 db bne :RowLoop
; clear bottom line
0e11: a0 27 ldy #39
0e13: a9 00 lda #$00
0e15: 99 d0 3f :ClearLoop sta HIRES_PAGE_1+$1fd0,y
0e18: 88 dey
0e19: 10 fa bpl :ClearLoop
0e1b: 60 rts
********************************************************************************
* Handle BOX,X0,Y0,X1,Y1,drawMode,isFilled *
* *
* Draws a rectangle. *
* *
* On entry: *
* $F9/FA/FB: x0,y0 (top left) *
* $FC/FD/FE: x1,y1 (bottom right) *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
* $FF: fill flag (0=outline, nonzero=filled) *
********************************************************************************
0e1c: a5 ff HandleBOX lda ARG_FF ;filled rect?
0e1e: d0 66 bne FillBox ;yes, branch
0e20: a5 f9 lda ARG_X0
0e22: 8d 5b 14 sta scratch0
0e25: a5 fa lda ARG_X0+1
0e27: 8d 5c 14 sta scratch1
0e2a: a5 fe lda ARG_Y1
0e2c: 8d 5e 14 sta scratch3
0e2f: a5 fb lda ARG_Y0
0e31: 8d 5d 14 sta scratch2
0e34: 85 fe sta ARG_Y1
0e36: a5 fc lda ARG_X1
0e38: 8d 5f 14 sta scratch4
0e3b: a5 fd lda ARG_X1+1
0e3d: 8d 60 14 sta scratch5
0e40: 20 d0 08 jsr HandleLINE ;draw X0,Y0 to X1,Y0
0e43: 20 60 08 jsr HandleDOT ;plot X1,Y0
0e46: ad 5f 14 lda scratch4
0e49: 85 fc sta ARG_X1
0e4b: ad 60 14 lda scratch5
0e4e: 85 fd sta ARG_X1+1
0e50: ad 5e 14 lda scratch3
0e53: 85 fe sta ARG_Y1
0e55: 20 d0 08 jsr HandleLINE ;plot X1,Y0 to X1,Y1
0e58: 20 60 08 jsr HandleDOT ;plot X1,Y1
0e5b: ad 5e 14 lda scratch3
0e5e: 85 fe sta ARG_Y1
0e60: ad 5b 14 lda scratch0
0e63: 85 fc sta ARG_X1
0e65: ad 5c 14 lda scratch1
0e68: 85 fd sta ARG_X1+1
0e6a: 20 d0 08 jsr HandleLINE ;plot X1,Y1 to X0,Y1
0e6d: 20 60 08 jsr HandleDOT ;plot X0,Y1
0e70: ad 5b 14 lda scratch0
0e73: 85 fc sta ARG_X1
0e75: ad 5c 14 lda scratch1
0e78: 85 fd sta ARG_X1+1
0e7a: ad 5d 14 lda scratch2
0e7d: 85 fe sta ARG_Y1
0e7f: 20 d0 08 jsr HandleLINE ;plot X0,y1 to X0,Y0
0e82: 20 60 08 jsr HandleDOT ;plot X0,Y0
0e85: 60 rts
0e86: a2 01 FillBox ldx #$01 ;configure Y direction
0e88: a5 fe lda ARG_Y1 ;Y1 > Y0?
0e8a: 38 sec
0e8b: e5 fb sbc ARG_Y0
0e8d: b0 02 bcs L0E91 ;yes, count up
0e8f: a2 ff ldx #$ff ;no, count down
0e91: 8e 5d 14 L0E91 stx scratch2
0e94: a5 fe lda ARG_Y1 ;save X0/Y0/Y1
0e96: 8d 5e 14 sta scratch3
0e99: a5 f9 lda ARG_X0
0e9b: 8d 5b 14 sta scratch0
0e9e: a5 fa lda ARG_X0+1
0ea0: 8d 5c 14 sta scratch1
0ea3: a5 fb lda ARG_Y0 ;copy Y0 to Y1
0ea5: 85 fe sta ARG_Y1
0ea7: a5 fc lda ARG_X1 ;save X1
0ea9: 8d 5f 14 sta scratch4
0eac: a5 fd lda ARG_X1+1
0eae: 8d 60 14 sta scratch5
0eb1: 20 d0 08 :FillBoxLoop jsr HandleLINE ;draw X0,Y0 to X1,Y1
0eb4: ad 5b 14 lda scratch0 ;restore X0/X1
0eb7: 85 f9 sta ARG_X0
0eb9: ad 5c 14 lda scratch1
0ebc: 85 fa sta ARG_X0+1
0ebe: ad 5f 14 lda scratch4
0ec1: 85 fc sta ARG_X1
0ec3: ad 60 14 lda scratch5
0ec6: 85 fd sta ARG_X1+1
0ec8: a5 fb lda ARG_Y0 ;get Y0
0eca: cd 5e 14 cmp scratch3 ;are we done yet?
0ecd: f0 0b beq :Done
0ecf: 18 clc ;update Y
0ed0: 6d 5d 14 adc scratch2
0ed3: 85 fb sta ARG_Y0 ;stick into Y0/Y1
0ed5: 85 fe sta ARG_Y1
0ed7: 4c b1 0e jmp :FillBoxLoop
0eda: 60 :Done rts
********************************************************************************
* Handle SWITCHC *
* *
* Flips the high bits on the bit patterns we use to draw points. Affects any *
* routine that uses DOT to perform rendering. *
********************************************************************************
0edb: a2 00 HandleSWITCHC ldx #$00
0edd: bd 4e 1a :Loop lda mod7_lo,x ;do 0-139 and 140-279 in parallel
0ee0: 49 80 eor #$80
0ee2: 9d 4e 1a sta mod7_lo,x
0ee5: bd da 1a lda mod7_lo+140,x
0ee8: 49 80 eor #$80
0eea: 9d da 1a sta mod7_lo+140,x
0eed: e8 inx
0eee: e0 8c cpx #140
0ef0: d0 eb bne :Loop
0ef2: 60 rts
********************************************************************************
* Handle CHARSET,X0,Y0,itemIndex,dataPtr,drawMode *
* *
* Draws a graphic from a compressed bitmap. *
* *
* On entry: *
* $F9/FA/FB: x0,y0 (top left) *
* $1E: item index *
* $E8/E9: pointer to image data set *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
* *
* The image data set looks like this: *
* +00 max index (count + 1) *
* +01 image0 params (4 bytes) *
* +05 image1 params (4 bytes) *
* ... *
* +xx image0 data *
* *
* The image parameter blocks look like: *
* +00/01 offset to data from start of set *
* +02 width, in pixels *
* +03 height, in pixels *
* *
* The image data itself is 8-bit bytes, with one bit per pixel. If a bit is *
* set, the pixel should be drawn; otherwise, the existing pixel value should *
* be left alone. This is a compact representation of a monochrome bitmap with *
* transparency. *
********************************************************************************
• Clear variables
]hptr .var $06 {addr/2}
]src_ptr .var $08 {addr/2}
]data_offset .var $19 {addr/2}
]item_index .var $1e {addr/1}
]num_cols .var $fc {addr/1}
]num_rows .var $fd {addr/1}
]col_count .var $fe {addr/1}
]row_count .var $ff {addr/1}
0ef3: a6 1e HandleCHARSET ldx ]item_index ;get index
0ef5: a0 00 ldy #$00
0ef7: b1 e8 lda (ARG_EXT_PTR),y ;check vs. max
0ef9: c5 1e cmp ]item_index
0efb: b0 0a bcs :InRange ;max is >= index, good
0efd: 20 dd fb jsr MON_BELL1 ;failed
0f00: 20 dd fb jsr MON_BELL1
0f03: 20 dd fb jsr MON_BELL1
0f06: 60 rts
0f07: 98 :InRange tya ;set A=0
0f08: 86 08 stx ]src_ptr ;compute offset = index * 4
0f0a: 85 09 sta ]src_ptr+1
0f0c: 06 08 asl ]src_ptr
0f0e: 26 09 rol ]src_ptr+1
0f10: 06 08 asl ]src_ptr
0f12: 26 09 rol ]src_ptr+1
0f14: a5 08 lda ]src_ptr ;add offset to external data ptr
0f16: 38 sec ;set carry to add +1
0f17: 65 e8 adc ARG_EXT_PTR
0f19: 85 08 sta ]src_ptr
0f1b: a5 09 lda ]src_ptr+1
0f1d: 65 e9 adc ARG_EXT_PTR+1
0f1f: 85 09 sta ]src_ptr+1
; Pull shape offset, width, and height out of external data buffer.
0f21: a0 00 ldy #$00
0f23: b1 08 lda (]src_ptr),y
0f25: 85 19 sta ]data_offset
0f27: c8 iny
0f28: b1 08 lda (]src_ptr),y
0f2a: 85 1a sta ]data_offset+1
0f2c: c8 iny
0f2d: b1 08 lda (]src_ptr),y
0f2f: 85 fc sta ]num_cols
0f31: c8 iny
0f32: b1 08 lda (]src_ptr),y
0f34: 85 fd sta ]num_rows
0f36: a5 19 lda ]data_offset
0f38: 18 clc
0f39: 65 e8 adc ARG_EXT_PTR
0f3b: 85 08 sta ]src_ptr ;set src pointer
0f3d: a5 1a lda ]data_offset+1
0f3f: 65 e9 adc ARG_EXT_PTR+1
0f41: 85 09 sta ]src_ptr+1
]bit_mask .var $1d {addr/1}
]saved_x0 .var $f9 {addr/2}
0f43: a5 fd FromPenguin lda ]num_rows
0f45: 85 ff sta ]row_count
0f47: a9 01 lda #$01 ;bit to extract
0f49: 85 1d sta ]bit_mask
0f4b: a5 f9 lda ]saved_x0
0f4d: 85 19 sta ]data_offset
0f4f: a5 fa lda ]saved_x0+1
0f51: 85 1a sta ]data_offset+1
0f53: a5 fc :LineLoop lda ]num_cols
0f55: 85 fe sta ]col_count
; set up hi-res ptr
0f57: a4 fb ldy ARG_Y0
0f59: b9 b6 17 lda hr_addr_lo,y
0f5c: 85 06 sta ]hptr
0f5e: b9 76 18 lda hr_addr_hi,y
0f61: 0d 85 14 ora hpage
0f64: 85 07 sta ]hptr+1
; plot points based on bits in data
0f66: a0 00 :DrawLoop ldy #$00 ;get byte of data
0f68: b1 08 lda (]src_ptr),y
0f6a: 25 1d and ]bit_mask ;is the bit set?
0f6c: f0 03 beq :NoDraw ;nope, don't draw here
0f6e: 20 73 08 jsr HandleDOT_1 ;draw at X0
0f71: 06 1d :NoDraw asl ]bit_mask ;move to the next bit
0f73: 90 08 bcc :NoInc ;if we haven't done all 8 bits yet, continue
0f75: e6 1d inc ]bit_mask ;set bit_mask = 1
0f77: e6 08 inc ]src_ptr ;move to the next byte
0f79: d0 02 bne :NoInc ;(note we only do this at 8 bits; there are no
0f7b: e6 09 inc ]src_ptr+1 ; padding bits for non-multiple of 8 rows)
0f7d: e6 f9 :NoInc inc ]saved_x0 ;advance X coordinate
0f7f: d0 02 bne :NoIncX
0f81: e6 fa inc ]saved_x0+1
0f83: c6 fe :NoIncX dec ]col_count ;count down number of pixels in this row
0f85: d0 df bne :DrawLoop ;not done yet
0f87: e6 fb inc ARG_Y0 ;row done, move to the next
0f89: a5 19 lda ]data_offset ;restore X0
0f8b: 85 f9 sta ]saved_x0
0f8d: a5 1a lda ]data_offset+1
0f8f: 85 fa sta ]saved_x0+1
0f91: c6 ff dec ]row_count ;done with all rows?
0f93: d0 be bne :LineLoop ;not yet
0f95: 60 rts
********************************************************************************
* Handle BDRW,X0,Y0,shapeIndex,dataPtr *
* *
* Draws a bitmap on the hi-res screen. *
* *
* On entry: *
* $F9/FA/FB: x0,y0 *
* $1E: shape index *
* $E8/E9: shape data ptr *
********************************************************************************
• Clear variables
]hptr .var $06 {addr/2}
]col_ctr .var $08 {addr/1}
]src_ptr .var $19 {addr/2}
]row_ctr .var $1b {addr/1}
]shape_index .var $1e {addr/1}
0f96: a5 e8 HandleBDRW lda ARG_EXT_PTR
0f98: 85 19 sta ]src_ptr
0f9a: a5 e9 lda ARG_EXT_PTR+1
0f9c: 85 1a sta ]src_ptr+1
0f9e: a6 1e ldx ]shape_index ;get the index, and multiply by 84
0fa0: ca :Mult84 dex ; to get the shape offset
0fa1: 30 10 bmi :GotPtr
0fa3: a5 19 lda ]src_ptr
0fa5: 18 clc
0fa6: 69 54 adc #84 ;4 * 21
0fa8: 85 19 sta ]src_ptr
0faa: a5 1a lda ]src_ptr+1
0fac: 69 00 adc #$00
0fae: 85 1a sta ]src_ptr+1
0fb0: 4c a0 0f jmp :Mult84
0fb3: a9 00 :GotPtr lda #$00
0fb5: 85 1b :RowLoop sta ]row_ctr
0fb7: a5 fb lda ARG_Y0 ;set up hi-res address
0fb9: 18 clc
0fba: 65 1b adc ]row_ctr
0fbc: a8 tay
0fbd: b9 b6 17 lda hr_addr_lo,y
0fc0: 85 06 sta ]hptr
0fc2: b9 76 18 lda hr_addr_hi,y
0fc5: 0d 85 14 ora hpage
0fc8: 85 07 sta ]hptr+1
0fca: a9 00 lda #$00 ;start from left column
0fcc: 85 08 sta ]col_ctr
0fce: a0 00 :ColLoop ldy #$00
0fd0: b1 19 lda (]src_ptr),y
0fd2: aa tax
0fd3: e6 19 inc ]src_ptr
0fd5: d0 02 bne :NoInc
0fd7: e6 1a inc ]src_ptr+1
0fd9: a5 f9 :NoInc lda ARG_X0
0fdb: 18 clc
0fdc: 65 08 adc ]col_ctr
0fde: a8 tay
0fdf: 8a txa
0fe0: 91 06 sta (]hptr),y
0fe2: e6 08 inc ]col_ctr
0fe4: a5 08 lda ]col_ctr
0fe6: c9 04 cmp #4 ;end of column?
0fe8: d0 e4 bne :ColLoop ;not yet
0fea: e6 1b inc ]row_ctr
0fec: a5 1b lda ]row_ctr
0fee: c9 15 cmp #21 ;end of bitmap?
0ff0: d0 c3 bne :RowLoop ;not yet
0ff2: 60 rts
********************************************************************************
* Handle CIRCLE,color,X0,Y0,radius,drawMode,fillFlag *
* *
* Draws an outline or filled circle. *
* *
* On entry: *
* $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue, 4=white) *
* $F9,FA,FB: x0,y0 (center) *
* $1B: radius *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
* $FF: fillFlag (0=outline, nonzero=filled) *
* *
* (Note the color index also allows 4=white.) *
********************************************************************************
• Clear variables
]y_val .var $19 {addr/1}
]x_val .var $1a {addr/1}
]radius .var $1b {addr/1}
]d_val .var $1d {addr/1}
0ff3: a5 1b HandleCIRCLE lda ]radius ;check radius
0ff5: d0 04 bne :NonzeroRadius
0ff7: 20 60 08 jsr HandleDOT ;just draw a dot at X0,Y0
0ffa: 60 rts
0ffb: 85 19 :NonzeroRadius sta ]y_val
0ffd: 49 ff eor #$ff
0fff: 85 1d sta ]d_val ;should be d = 1 - rad
1001: e6 1d inc ]d_val
1003: a9 00 lda #$00
1005: 85 1a sta ]x_val
1007: a5 f9 lda ARG_X0
1009: 85 fc sta ARG_X1
100b: a5 fa lda ARG_X0+1
100d: 85 fd sta ARG_X1+1
100f: a5 fb lda ARG_Y0
1011: 85 fe sta ARG_Y1
; Draw a pair of points or a horizontal line for all four quadrants.
1013: a5 fc :CircleLoop lda ARG_X1
1015: 38 sec
1016: e5 1a sbc ]x_val
1018: 85 f9 sta ARG_X0
101a: a5 fd lda ARG_X1+1
101c: e9 00 sbc #$00
101e: 85 fa sta ARG_X0+1
1020: a5 fe lda ARG_Y1
1022: 38 sec
1023: e5 19 sbc ]y_val
1025: 85 fb sta ARG_Y0
1027: 20 c1 10 jsr PushXY
102a: a5 fc lda ARG_X1
102c: 18 clc
102d: 65 1a adc ]x_val
102f: 85 f9 sta ARG_X0
1031: a5 fd lda ARG_X1+1
1033: 69 00 adc #$00
1035: 85 fa sta ARG_X0+1
1037: 20 d1 10 jsr DrawPair ;first
103a: a5 fe lda ARG_Y1
103c: 18 clc
103d: 65 19 adc ]y_val
103f: 85 fb sta ARG_Y0
1041: 20 c1 10 jsr PushXY
1044: a5 fc lda ARG_X1
1046: 38 sec
1047: e5 1a sbc ]x_val
1049: 85 f9 sta ARG_X0
104b: a5 fd lda ARG_X1+1
104d: e9 00 sbc #$00
104f: 85 fa sta ARG_X0+1
1051: 20 d1 10 jsr DrawPair ;second
1054: a5 fc lda ARG_X1
1056: 18 clc
1057: 65 19 adc ]y_val
1059: 85 f9 sta ARG_X0
105b: a5 fd lda ARG_X1+1
105d: 69 00 adc #$00
105f: 85 fa sta ARG_X0+1
1061: a5 fe lda ARG_Y1
1063: 38 sec
1064: e5 1a sbc ]x_val
1066: 85 fb sta ARG_Y0
1068: 20 c1 10 jsr PushXY
106b: a5 fc lda ARG_X1
106d: 38 sec
106e: e5 19 sbc ]y_val
1070: 85 f9 sta ARG_X0
1072: a5 fd lda ARG_X1+1
1074: e9 00 sbc #$00
1076: 85 fa sta ARG_X0+1
1078: 20 d1 10 jsr DrawPair ;third
107b: a5 fe lda ARG_Y1
107d: 18 clc
107e: 65 1a adc ]x_val
1080: 85 fb sta ARG_Y0
1082: 20 c1 10 jsr PushXY
1085: a5 fc lda ARG_X1
1087: 18 clc
1088: 65 19 adc ]y_val
108a: 85 f9 sta ARG_X0
108c: a5 fd lda ARG_X1+1
108e: 69 00 adc #$00
1090: 85 fa sta ARG_X0+1
1092: 20 d1 10 jsr DrawPair ;fourth
; Do update. The math here is not quite correct (compared to what Bresenham
; does), which is why large circles look distorted. For example, try
; &CIRCLE,4,139,95,90,0,1.
1095: a5 1a lda ]x_val ;d += (x << 1)
1097: 0a asl A
1098: 38 sec
1099: 65 1d adc ]d_val
109b: 85 1d sta ]d_val
109d: e6 1a inc ]x_val ;x++
109f: a5 1d lda ]d_val ;d < 0?
10a1: 30 11 bmi :NegD ;yes, branch
10a3: e6 1d inc ]d_val ;d += 2
10a5: e6 1d inc ]d_val
10a7: 06 19 asl ]y_val ;y *= 2 (temporarily)
10a9: a5 1d lda ]d_val ;d -= (y * 2)
10ab: 38 sec
10ac: e5 19 sbc ]y_val
10ae: 85 1d sta ]d_val
10b0: 46 19 lsr ]y_val ;y /= 2
10b2: c6 19 dec ]y_val ;y--
10b4: a5 1a :NegD lda ]x_val ;is x <= y?
10b6: 38 sec
10b7: e5 19 sbc ]y_val
10b9: 90 03 bcc :Cont
10bb: f0 01 beq :Cont
10bd: 60 rts
10be: 4c 13 10 :Cont jmp :CircleLoop
10c1: a5 f9 PushXY lda ARG_X0
10c3: 8d 56 14 sta saved_xlo
10c6: a5 fa lda ARG_X0+1
10c8: 8d 57 14 sta saved_xhi
10cb: a5 fb lda ARG_Y0
10cd: 8d 58 14 sta saved_y
10d0: 60 rts
; Draws a pair of dots or a horizontal line. Used for circle drawing.
10d1: a5 f9 DrawPair lda ARG_X0
10d3: 8d 59 14 sta saved_x2l
10d6: a5 fa lda ARG_X0+1
10d8: 8d 5a 14 sta saved_x2h
10db: a2 06 ldx #$06 ;save state
10dd: b5 f9 :SaveLoop lda ARG_X0,x
10df: 9d 5b 14 sta scratch0,x
10e2: ca dex
10e3: 10 f8 bpl :SaveLoop
10e5: a2 05 ldx #$05
10e7: b5 19 :SaveLoop2 lda ]y_val,x
10e9: 9d 62 14 sta scratch5+2,x
10ec: ca dex
10ed: 10 f8 bpl :SaveLoop2
10ef: a5 1f lda ARG_COLOR ;check desired color
10f1: c9 04 cmp #$04 ;solid white?
10f3: 90 4c bcc ColorCircle ;no, draw with color calls
10f5: ad 56 14 lda saved_xlo ;yes, draw white points or lines
10f8: 85 f9 sta ARG_X0
10fa: ad 57 14 lda saved_xhi
10fd: 85 fa sta ARG_X0+1
10ff: ad 58 14 lda saved_y
1102: 85 fb sta ARG_Y0
1104: a5 ff lda ARG_FF ;filled circle?
1106: d0 13 bne DrawCircleLine ;yes, branch
1108: 20 60 08 jsr HandleDOT ;no, just plot a dot
110b: ad 59 14 lda saved_x2l
110e: 85 f9 sta ARG_X0
1110: ad 5a 14 lda saved_x2h
1113: 85 fa sta ARG_X0+1
1115: 20 60 08 jsr HandleDOT ;and another dot
1118: 4c 2c 11 jmp RestoreCircleCoord
111b: a5 fb DrawCircleLine lda ARG_Y0 ;horizontal line
111d: 85 fe sta ARG_Y1
111f: ad 59 14 lda saved_x2l
1122: 85 fc sta ARG_X1
1124: ad 5a 14 lda saved_x2h
1127: 85 fd sta ARG_X1+1
1129: 20 d0 08 jsr HandleLINE
RestoreCircleCoord
112c: a2 06 ldx #$06
112e: bd 5b 14 :Loop lda scratch0,x
1131: 95 f9 sta ARG_X0,x
1133: ca dex
1134: 10 f8 bpl :Loop
1136: a2 05 ldx #$05
1138: bd 62 14 :Loop2 lda scratch5+2,x
113b: 95 19 sta ]y_val,x
113d: ca dex
113e: 10 f8 bpl :Loop2
1140: 60 rts
1141: 4e 5a 14 ColorCircle lsr saved_x2h ;convert X from 0-279 to 0-139
1144: 6e 59 14 ror saved_x2l
1147: 4e 57 14 lsr saved_xhi
114a: 6e 56 14 ror saved_xlo
114d: ad 56 14 lda saved_xlo
1150: 85 f9 sta ARG_X0
1152: ad 58 14 lda saved_y
1155: 85 fb sta ARG_Y0
1157: a5 ff lda ARG_FF ;filled circle?
1159: d0 0e bne :FilledColor ;no, draw a line
115b: 20 8a 11 jsr HandleCDOT ;yes, draw a couple of dots
115e: ad 59 14 lda saved_x2l
1161: 85 f9 sta ARG_X0
1163: 20 8a 11 jsr HandleCDOT
1166: 4c 2c 11 jmp RestoreCircleCoord
1169: a5 fb :FilledColor lda ARG_Y0
116b: 85 fe sta ARG_Y1
116d: ad 59 14 lda saved_x2l
1170: 85 fc sta ARG_X1
1172: 20 e7 11 jsr HandleCLINE
1175: 4c 2c 11 jmp RestoreCircleCoord
********************************************************************************
* Handle PENGUIN,X0,Y0,drawMode *
* *
* Draws a penguin. Seriously. *
* *
* $F9/FA/FB: x0,y0 (where X is 0-139) *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
********************************************************************************
1178: a9 36 HandlePENGUIN lda #<penguin_data
117a: 85 08 sta $08
117c: a9 14 lda #>penguin_data
117e: 85 09 sta $09
1180: a9 10 lda #$10
1182: 85 fc sta ARG_X1
1184: 85 fd sta ARG_X1+1 ;item count
1186: 20 43 0f jsr FromPenguin
1189: 60 rts
********************************************************************************
* Handle CDOT,colorIndex,X0,Y0,drawMode *
* *
* On entry: *
* $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue) *
* $F9/FA/FB: x0,y0 (where X is 0-139) *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
* *
* X/Y args are range-checked for validity. *
********************************************************************************
• Clear variables
]hptr .var $06 {addr/2}
118a: a4 fb HandleCDOT ldy ARG_Y0 ;range check Y coord
118c: c0 c0 cpy #192
118e: b0 4c bcs :Done ;no good
1190: b9 b6 17 lda hr_addr_lo,y ;set up base address
1193: 85 06 sta ]hptr
1195: b9 76 18 lda hr_addr_hi,y
1198: 0d 85 14 ora hpage
119b: 85 07 sta ]hptr+1
119d: a6 f9 HandleCDOT_1 ldx ARG_X0 ;range check X coord
119f: e0 8c cpx #140
11a1: b0 39 bcs :Done
11a3: a5 1f lda ARG_COLOR ;get color index
11a5: c9 02 cmp #$02 ;>= 2?
11a7: 10 09 bpl :UseShifted ;yes, use second table
11a9: bd 86 14 lda div35_1,x ;0 or 1, use first table
11ac: a8 tay
11ad: bd 12 15 lda mod35_1,x
11b0: d0 07 bne :Cont ;(always)
11b2: bd 9e 15 :UseShifted lda div35_2,x
11b5: a8 tay
11b6: bd 2a 16 lda mod35_2,x
; Now Y=byte offset, X=pixel mask.
11b9: aa :Cont tax
11ba: a5 1f lda ARG_COLOR ;check low bit of color index
11bc: 4a lsr A
11bd: 90 09 bcc L11C8 ;clear, so clear hi bit on screen
11bf: a9 80 lda #$80 ;set, so set hi bit on screen
11c1: 11 06 ora (]hptr),y
11c3: 91 06 sta (]hptr),y
11c5: 4c ce 11 jmp :DoDraw
11c8: a9 7f L11C8 lda #$7f
11ca: 31 06 and (]hptr),y
11cc: 91 06 sta (]hptr),y
11ce: 8a :DoDraw txa
11cf: a6 1c ldx ARG_DRAW_MODE ;drawMode
11d1: f0 0a beq L11DD ;draw
11d3: ca dex
11d4: d0 0c bne L11E2 ;invert
11d6: 49 ff eor #$ff ;erase
11d8: 31 06 and (]hptr),y
11da: 91 06 sta (]hptr),y
11dc: 60 :Done rts
11dd: 11 06 L11DD ora (]hptr),y
11df: 91 06 sta (]hptr),y
11e1: 60 rts
11e2: 51 06 L11E2 eor (]hptr),y
11e4: 91 06 sta (]hptr),y
11e6: 60 rts
********************************************************************************
* Handle CLINE,colorIndex,X0,Y0,X1,Y1,drawMode *
* *
* On entry: *
* $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue) *
* $F9/FA/FB: x0,y0 (where X0 is 0-139) *
* $FC/FD/FE: x1,y1 (where x1 is 0-139) *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
* *
* On exit: *
* $F9/FA/FB holds 2nd coordinate (so you can chain calls) *
********************************************************************************
• Clear variables
]move_dir .var $08 {addr/1}
]tmp_x .var $19 {addr/1}
]tmp_y .var $1b {addr/1}
]delta_x .var $1e {addr/1}
]delta_y .var $ff {addr/1}
11e7: a5 fc HandleCLINE lda ARG_X1 ;save these for later
11e9: 8d 56 14 sta saved_xlo
11ec: a5 fe lda ARG_Y1
11ee: 8d 57 14 sta saved_xhi
11f1: a5 fb lda ARG_Y0 ;compute y0 - y1
11f3: 38 sec
11f4: e5 fe sbc ARG_Y1 ;is y0 < y1?
11f6: b0 05 bcs :NoYFlip ;no, branch
11f8: a5 fe lda ARG_Y1 ;compute y1 - y0
11fa: 38 sec
11fb: e5 fb sbc ARG_Y0
11fd: 85 ff :NoYFlip sta ]delta_y
11ff: a5 fc :ComputeDeltaX lda ARG_X1 ;compute x1 - x0
1201: 38 sec
1202: e5 f9 sbc ARG_X0 ;is x1 < x0?
1204: b0 06 bcs :GotDelta ;no, branch
1206: 20 08 13 jsr SwapXY ;yes, swap so we're drawing from left to right
1209: 4c ff 11 jmp :ComputeDeltaX
120c: 85 1e :GotDelta sta ]delta_x ;check for special cases
120e: f0 0e beq :Vertical
1210: a5 ff lda ]delta_y
1212: f0 2a beq :Horizontal
1214: a5 1e lda ]delta_x ;compare the deltas
1216: 38 sec
1217: e5 ff sbc ]delta_y
1219: b0 49 bcs :HorizDom ;delta X > delta Y, horizontally dominant
121b: 4c b8 12 jmp :VertDom
121e: 20 8a 11 :Vertical jsr HandleCDOT ;draw a dot
1221: a5 ff lda ]delta_y ;check line length
1223: d0 01 bne :DrawVert ;nonzero, so draw line
1225: 60 rts
1226: a5 fe :DrawVert lda ARG_Y1 ;is y1 < y0?
1228: 38 sec
1229: e5 fb sbc ARG_Y0
122b: b0 03 bcs :VertLoop ;no, we're good
122d: 20 08 13 jsr SwapXY ;swap so y0 is on top
1230: e6 fb :VertLoop inc ARG_Y0 ;inc since we already plotted one point
1232: 20 8a 11 jsr HandleCDOT ;plot the next point
1235: a5 fb lda ARG_Y0 ;are we done?
1237: c5 fe cmp ARG_Y1
1239: d0 f5 bne :VertLoop ;not yet
123b: 4c fd 12 jmp CopySavedToX0
123e: 20 8a 11 :Horizontal jsr HandleCDOT ;draw a dot
1241: e6 f9 :HorizLoop inc ARG_X0 ;move right
1243: 20 9d 11 jsr HandleCDOT_1 ;draw another dot
1246: a5 f9 lda ARG_X0 ;are we done?
1248: c5 fc cmp ARG_X1
124a: d0 f5 bne :HorizLoop ;not yet
124c: 4c fd 12 jmp CopySavedToX0
124f: e6 f9 :Diagonal inc ARG_X0 ;always move right
1251: a5 fb lda ARG_Y0 ;up or down
1253: 18 clc
1254: 65 08 adc ]move_dir
1256: 85 fb sta ARG_Y0
1258: 20 8a 11 jsr HandleCDOT ;draw a dot
125b: a5 fb lda ARG_Y0 ;done?
125d: c5 fe cmp ARG_Y1
125f: d0 ee bne :Diagonal ;not yet
1261: 4c fd 12 jmp CopySavedToX0
1264: 20 8a 11 :HorizDom jsr HandleCDOT ;draw a dot
1267: a5 1e lda ]delta_x
1269: 85 19 sta ]tmp_x
126b: a5 fe lda ARG_Y1 ;check for pure horizontal
126d: 38 sec
126e: e5 fb sbc ARG_Y0
1270: f0 cf beq :HorizLoop ;yup, go do that
1272: 90 06 bcc :HorizUpward ;which direction are we moving?
1274: a9 01 lda #$01 ;downward
1276: 85 08 sta ]move_dir
1278: d0 04 bne L127E
127a: a9 ff :HorizUpward lda #$ff ;upward
127c: 85 08 sta ]move_dir
127e: a5 1e L127E lda ]delta_x ;check for diagonal
1280: c5 ff cmp ]delta_y
1282: f0 cb beq :Diagonal ;yup, go do that
1284: a5 1e lda ]delta_x ;update deltas
1286: 38 sec
1287: e5 ff sbc ]delta_y
1289: 85 1e sta ]delta_x
128b: a5 1e :HorizDomLoop lda ]delta_x
128d: 38 sec
128e: e5 ff sbc ]delta_y
1290: 85 1e sta ]delta_x
1292: 90 08 bcc :UpdateY ;need to update the Y coord, branch
1294: e6 f9 inc ARG_X0 ;just update X this time
1296: 20 9d 11 jsr HandleCDOT_1 ;draw
1299: 4c af 12 jmp :HorizCont
129c: a5 1e :UpdateY lda ]delta_x ;update deltas
129e: 18 clc
129f: 65 19 adc ]tmp_x
12a1: 85 1e sta ]delta_x
12a3: a5 fb lda ARG_Y0 ;update Y coord
12a5: 18 clc
12a6: 65 08 adc ]move_dir
12a8: 85 fb sta ARG_Y0
12aa: e6 f9 inc ARG_X0 ;move right
12ac: 20 8a 11 jsr HandleCDOT ;draw
12af: a5 f9 :HorizCont lda ARG_X0 ;are we done?
12b1: c5 fc cmp ARG_X1
12b3: d0 d6 bne :HorizDomLoop ;not yet
12b5: 4c fd 12 jmp CopySavedToX0
12b8: a5 fe :VertDom lda ARG_Y1 ;is y1 > y0?
12ba: 38 sec
12bb: e5 fb sbc ARG_Y0
12bd: b0 09 bcs :XRight ;yes, all is well
12bf: 20 08 13 jsr SwapXY ;nope, swap so y0 is on top
12c2: a9 ff lda #$ff ;we were setup for left-to-right; now X will move
12c4: 85 08 sta ]move_dir ; left on each step
12c6: 30 04 bmi :GotMove ;(always)
12c8: a9 01 :XRight lda #$01 ;move X to the right
12ca: 85 08 sta ]move_dir
12cc: a5 ff :GotMove lda ]delta_y
12ce: 85 1b sta ]tmp_y
12d0: 85 19 sta ]tmp_x
12d2: 38 sec
12d3: e5 1e sbc ]delta_x
12d5: 85 ff sta ]delta_y
12d7: 20 8a 11 jsr HandleCDOT ;draw
12da: a5 ff :VertDomLoop lda ]delta_y ;update deltas
12dc: 38 sec
12dd: e5 1e sbc ]delta_x
12df: 85 ff sta ]delta_y
12e1: b0 0e bcs :DoDraw ;just move Y, branch
12e3: a5 ff lda ]delta_y ;time to move X
12e5: 18 clc
12e6: 65 19 adc ]tmp_x
12e8: 85 ff sta ]delta_y
12ea: a5 f9 lda ARG_X0
12ec: 18 clc
12ed: 65 08 adc ]move_dir
12ef: 85 f9 sta ARG_X0
12f1: e6 fb :DoDraw inc ARG_Y0 ;move down
12f3: 20 8a 11 jsr HandleCDOT ;draw
12f6: c6 1b dec ]tmp_y ;done?
12f8: d0 e0 bne :VertDomLoop ;not yet
12fa: 4c fd 12 jmp CopySavedToX0
; Copies the saved copy of X1/Y1 into X0/Y0.
12fd: ad 56 14 CopySavedToX0 lda saved_xlo
1300: 85 f9 sta ARG_X0
1302: ad 57 14 lda saved_xhi
1305: 85 fb sta ARG_Y0
1307: 60 rts
; Swap X0,Y0 with X1,Y1, ignoring X0H/X1H.
1308: a5 f9 SwapXY lda ARG_X0
130a: a6 fc ldx ARG_X1
130c: 86 f9 stx ARG_X0
130e: 85 fc sta ARG_X1
1310: a5 fb lda ARG_Y0
1312: a4 fe ldy ARG_Y1
1314: 84 fb sty ARG_Y0
1316: 85 fe sta ARG_Y1
1318: 60 rts
********************************************************************************
* Handle CBOX,colorIndex,X0,Y0,X1,Y1,drawMode,fillFlag *
* *
* On entry: *
* $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue) *
* $F9/FA/FB: x0,y0 *
* $FC/FD/FE: x1,y1 *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
* $FF: fill flag (0=outline, nonzero=filled) *
********************************************************************************
1319: a5 ff HandleCBOX lda ]delta_y ;check fill flag
131b: d0 41 bne FillCBOX ;go do filled version
131d: a5 f9 lda ARG_X0
131f: 8d 5b 14 sta scratch0
1322: a5 fe lda ARG_Y1
1324: 8d 5e 14 sta scratch3
1327: a5 fb lda ARG_Y0
1329: 8d 5d 14 sta scratch2
132c: 85 fe sta ARG_Y1
132e: a5 fc lda ARG_X1
1330: 8d 5f 14 sta scratch4
1333: 20 e7 11 jsr HandleCLINE ;draw x0,y0 to x1,y0
1336: ad 5f 14 lda scratch4
1339: 85 fc sta ARG_X1
133b: ad 5e 14 lda scratch3
133e: 85 fe sta ARG_Y1
1340: 20 e7 11 jsr HandleCLINE ;draw x1,y0 to x1,y1
1343: ad 5e 14 lda scratch3
1346: 85 fe sta ARG_Y1
1348: ad 5b 14 lda scratch0
134b: 85 fc sta ARG_X1
134d: 20 e7 11 jsr HandleCLINE ;draw x1,y1 to x0,y1
1350: ad 5b 14 lda scratch0
1353: 85 fc sta ARG_X1
1355: ad 5d 14 lda scratch2
1358: 85 fe sta ARG_Y1
135a: 20 e7 11 jsr HandleCLINE ;draw x0,y1 to x0,y0
135d: 60 rts
135e: a2 01 FillCBOX ldx #$01 ;up or down?
1360: a5 fe lda ARG_Y1 ;is y1 < y0?
1362: 38 sec
1363: e5 fb sbc ARG_Y0
1365: b0 02 bcs :Y0Top ;no, y0 on top, branch
1367: a2 ff ldx #$ff ;yes, move upward
1369: 8e 5d 14 :Y0Top stx scratch2
136c: a5 fe lda ARG_Y1
136e: 8d 5e 14 sta scratch3
1371: a5 f9 lda ARG_X0
1373: 8d 5b 14 sta scratch0
1376: a5 fb lda ARG_Y0
1378: 85 fe sta ARG_Y1
137a: a5 fc lda ARG_X1
137c: 8d 5f 14 sta scratch4
137f: 20 e7 11 :FillLoop jsr HandleCLINE ;draw x0,y0 to x1,y0
1382: ad 5b 14 lda scratch0 ;restore x0/x1
1385: 85 f9 sta ARG_X0
1387: ad 5f 14 lda scratch4
138a: 85 fc sta ARG_X1
138c: a5 fb lda ARG_Y0 ;update y0/y1
138e: cd 5e 14 cmp scratch3 ;are we done?
1391: f0 0b beq :Done
1393: 18 clc
1394: 6d 5d 14 adc scratch2 ;move Y coords
1397: 85 fb sta ARG_Y0 ;set both (horizontal line)
1399: 85 fe sta ARG_Y1
139b: 4c 7f 13 jmp :FillLoop
139e: 60 :Done rts
********************************************************************************
* Handle CCHARSET,colorIndex,X0,Y0,itemIndex,dataPtr,drawMode *
* *
* Draws a graphic from a compressed bitmap. *
* *
* On entry: *
* $1F: colorIndex *
* $F9/FA/FB: x0,y0 (top left) *
* $1E: item index *
* $E8/E9: pointer to image data set *
* $1C: drawMode (0=draw, 1=erase, 2=invert) *
********************************************************************************
• Clear variables
]data_ptr .var $08 {addr/2}
]data_offset .var $19 {addr/2}
]width .var $fc {addr/1}
]height .var $fd {addr/1}
]row_ctr .var $ff {addr/1}
139f: a6 1e HandleCCHARSET ldx ARG_ITEM_INDEX ;requested item index
13a1: a0 00 ldy #$00
13a3: b1 e8 lda (ARG_EXT_PTR),y ;check table max
13a5: c5 1e cmp ARG_ITEM_INDEX ;is max >= our value?
13a7: b0 0a bcs :IndexOkay ;yes, branch
13a9: 20 dd fb jsr MON_BELL1
13ac: 20 dd fb jsr MON_BELL1
13af: 20 dd fb jsr MON_BELL1
13b2: 60 rts
13b3: 98 :IndexOkay tya ;A=0
13b4: 86 08 stx ]data_ptr ;store index
13b6: 85 09 sta ]data_ptr+1
13b8: 06 08 asl ]data_ptr ;multiply by 4
13ba: 26 09 rol ]data_ptr+1
13bc: 06 08 asl ]data_ptr
13be: 26 09 rol ]data_ptr+1
13c0: a5 08 lda ]data_ptr ;add the data ptr arg
13c2: 38 sec
13c3: 65 e8 adc ARG_EXT_PTR
13c5: 85 08 sta ]data_ptr
13c7: a5 09 lda ]data_ptr+1
13c9: 65 e9 adc ARG_EXT_PTR+1
13cb: 85 09 sta ]data_ptr+1
; Now data_ptr points at the item descriptor.
13cd: a0 00 ldy #$00
13cf: b1 08 lda (]data_ptr),y ;get the offset
13d1: 85 19 sta ]data_offset
13d3: c8 iny
13d4: b1 08 lda (]data_ptr),y
13d6: 85 1a sta ]data_offset+1
13d8: c8 iny
13d9: b1 08 lda (]data_ptr),y ;width in pixels
13db: 85 fc sta ]width
13dd: c8 iny
13de: b1 08 lda (]data_ptr),y ;height in pixels
13e0: 85 fd sta ]height
13e2: a5 19 lda ]data_offset
13e4: 18 clc
13e5: 65 e8 adc ARG_EXT_PTR ;set data_ptr to the bitmap data
13e7: 85 08 sta ]data_ptr ; by adding in the offset
13e9: a5 1a lda ]data_offset+1
13eb: 65 e9 adc ARG_EXT_PTR+1
13ed: 85 09 sta ]data_ptr+1
]hptr .var $06 {addr/2}
]saved_x0 .var $19 {addr/1}
]bit_mask .var $1d {addr/1}
]col_ctr .var $fe {addr/1}
13ef: a5 fd lda ]height ;init row counter
13f1: 85 ff sta ]row_ctr
13f3: a9 01 lda #$01
13f5: 85 1d sta ]bit_mask
13f7: a5 f9 lda ARG_X0
13f9: 85 19 sta ]saved_x0
13fb: a5 fc :RowLoop lda ]width ;init col counter
13fd: 85 fe sta ]col_ctr
13ff: a4 fb ldy ARG_Y0 ;get row
1401: b9 b6 17 lda hr_addr_lo,y ;find hi-res row address
1404: 85 06 sta ]hptr
1406: b9 76 18 lda hr_addr_hi,y
1409: 0d 85 14 ora hpage
140c: 85 07 sta ]hptr+1
140e: a0 00 :ColLoop ldy #$00 ;get byte of pixel data
1410: b1 08 lda (]data_ptr),y
1412: 25 1d and ]bit_mask ;extract bit
1414: f0 03 beq :NoDraw ;zero, don't draw
1416: 20 9d 11 jsr HandleCDOT_1 ;one, do draw
1419: 06 1d :NoDraw asl ]bit_mask ;advance to next bit
141b: 90 08 bcc :MoreBits ;more bits, branch
141d: e6 1d inc ]bit_mask ;set mask to $01
141f: e6 08 inc ]data_ptr ;advance to next byte
1421: d0 02 bne :MoreBits
1423: e6 09 inc ]data_ptr+1
1425: e6 f9 :MoreBits inc ARG_X0 ;move right
1427: c6 fe dec ]col_ctr ;more to do in this row?
1429: d0 e3 bne :ColLoop ;yes, branch
142b: e6 fb inc ARG_Y0 ;move down to next row
142d: a5 19 lda ]saved_x0 ;move back to left edge
142f: 85 f9 sta ARG_X0
1431: c6 ff dec ]row_ctr ;more to do?
1433: d0 c6 bne :RowLoop ;yes?
1435: 60 rts
; Penguin image data for CHARSET (16x16).
1436: e0 01 10 02+ penguin_data .bulk e00110028804083c080410021004500a500a5009c804040232064e08c00f0000
1456: b8 saved_xlo .dd1 $b8
1457: a5 saved_xhi .dd1 $a5
1458: b3 saved_y .dd1 $b3
1459: c0 saved_x2l .dd1 $c0
145a: c1 saved_x2h .dd1 $c1
145b: a0 scratch0 .dd1 $a0
145c: 85 scratch1 .dd1 $85
145d: a0 scratch2 .dd1 $a0
145e: a2 scratch3 .dd1 $a2
145f: a0 scratch4 .dd1 $a0
1460: e7 scratch5 .dd1 $e7
1461: a0 .dd1 $a0
1462: a0 .dd1 $a0
1463: a5 .dd1 $a5
1464: c5 .dd1 $c5
1465: 83 scratch10 .dd1 $83
1466: c2 .dd1 $c2
1467: e8 .dd1 $e8
1468: a0 .dd1 $a0
1469: a0 saved_1f .dd1 $a0
146a: 01 angle_xsign .dd1 $01
146b: 01 .dd1 $01
146c: ff .dd1 $ff
146d: ff .dd1 $ff
146e: 01 angle_ysign .dd1 $01
146f: ff .dd1 $ff
1470: ff .dd1 $ff
1471: 01 .dd1 $01
; Color values for CLR function.
1472: 00 2a 55 7f+ clr_color_table .bulk 002a557f80aad5ff ;even columns
147a: 00 55 2a 7f+ .bulk 00552a7f80d5aaff ;odd columns
; EOR values for SCFLIP
1482: 7f 80 ff flip_pattern .bulk 7f80ff
; Hi-res page we're currently working on ($20 or $40).
1485: 20 hpage .dd1 $20
;
; Color X coordinate (0-139) divided by 3.5 to get byte column.
;
1486: 00 00 00 01+ div35_1 .bulk 0000000101010102020203030303040404050505050606060707070708080809
+ 0909090a0a0a0b0b0b0b0c0c0c0d0d0d0d0e0e0e0f0f0f0f1010101111111112
+ 1212131313131414141515151516161617171717181818191919191a1a1a1b1b
+ 1b1b1c1c1c1d1d1d1d1e1e1e1f1f1f1f20202021212121222222232323232424
+ 242525252526262627272727
;
; Color X coordinate (0-139) mod 3.5 to get pixel value (green/orange).
;
1512: 02 08 20 01+ mod35_1 .bulk 0208200104104002082001041040020820010410400208200104104002082001
+ 0410400208200104104002082001041040020820010410400208200104104002
+ 0820010410400208200104104002082001041040020820010410400208200104
+ 1040020820010410400208200104104002082001041040020820010410400208
+ 200104104002082001041040
;
; Like div35_1, but shifted over one bit.
;
159e: 00 00 00 00+ div35_2 .bulk 0000000001010102020202030303040404040505050606060607070708080808
+ 0909090a0a0a0a0b0b0b0c0c0c0c0d0d0d0e0e0e0e0f0f0f1010101011111112
+ 1212121313131414141415151516161616171717181818181919191a1a1a1a1b
+ 1b1b1c1c1c1c1d1d1d1e1e1e1e1f1f1f20202020212121222222222323232424
+ 242425252526262626272727
;
; Like mod35_1, but shifted over 1 bit (purple/blue).
;
162a: 01 04 10 40+ mod35_2 .bulk 0104104002082001041040020820010410400208200104104002082001041040
+ 0208200104104002082001041040020820010410400208200104104002082001
+ 0410400208200104104002082001041040020820010410400208200104104002
+ 0820010410400208200104104002082001041040020820010410400208200104
+ 104002082001041040020820
;
; Sine/cosine values for LINESET angle.
;
16b6: 00 06 0c 12+ angle_sin .bulk 00060c12181f252b31373d444a4f555b61676d72787d83888d92979ca1a6abaf
+ b4b8bcc1c5c9ccd0d4d7dadde0e3e6e9ebedf0f2f4f5f7f8fafbfcfdfdfefefe
+ fefefefefdfdfcfbfaf8f7f5f4f2f0edebe9e6e3e0dddad7d4d0ccc9c5c1bcb8
+ b4afaba6a19c97928d88837d78726d67615b554f4a443d37312b251f18120c06
1736: fe fe fe fe+ angle_cos .bulk fefefefefdfdfcfbfaf8f7f5f4f2f0edebe9e6e3e0dddad7d4d0ccc9c5c1bcb8
+ b4afaba6a19c97928d88837d78726d67615b554f4a443d37312b251f18120c06
+ 00060c12181f252b31373d444a4f555b61676d72787d83888d92979ca1a6abaf
+ b4b8bcc1c5c9ccd0d4d7dadde0e3e6e9ebedf0f2f4f5f7f8fafbfcfdfdfefefe
;
; Hi-res row base addresses.
;
; The high byte doesn't have the page number included.
;
17b6: 00 00 00 00+ hr_addr_lo .bulk 0000000000000000808080808080808000000000000000008080808080808080
+ 0000000000000000808080808080808000000000000000008080808080808080
+ 2828282828282828a8a8a8a8a8a8a8a82828282828282828a8a8a8a8a8a8a8a8
+ 2828282828282828a8a8a8a8a8a8a8a82828282828282828a8a8a8a8a8a8a8a8
+ 5050505050505050d0d0d0d0d0d0d0d05050505050505050d0d0d0d0d0d0d0d0
+ 5050505050505050d0d0d0d0d0d0d0d05050505050505050d0d0d0d0d0d0d0d0
1876: 00 04 08 0c+ hr_addr_hi .bulk 0004080c1014181c0004080c1014181c0105090d1115191d0105090d1115191d
+ 02060a0e12161a1e02060a0e12161a1e03070b0f13171b1f03070b0f13171b1f
+ 0004080c1014181c0004080c1014181c0105090d1115191d0105090d1115191d
+ 02060a0e12161a1e02060a0e12161a1e03070b0f13171b1f03070b0f13171b1f
+ 0004080c1014181c0004080c1014181c0105090d1115191d0105090d1115191d
+ 02060a0e12161a1e02060a0e12161a1e03070b0f13171b1f03070b0f13171b1f
;
; Convert X coordinate (0-255) to hi-res column byte by dividing by 7.
;
1936: 00 00 00 00+ div7_lo .bulk 0000000000000001010101010101020202020202020303030303030304040404
+ 0404040505050505050506060606060606070707070707070808080808080809
+ 0909090909090a0a0a0a0a0a0a0b0b0b0b0b0b0b0c0c0c0c0c0c0c0d0d0d0d0d
+ 0d0d0e0e0e0e0e0e0e0f0f0f0f0f0f0f10101010101010111111111111111212
+ 1212121212131313131313131414141414141415151515151515161616161616
+ 161717171717171718181818181818191919191919191a1a1a1a1a1a1a1b1b1b
+ 1b1b1b1b1c1c1c1c1c1c1c1d1d1d1d1d1d1d1e1e1e1e1e1e1e1f1f1f1f1f1f1f
+ 2020202020202021212121212121222222222222222323232323232324242424
;
; Convert X coordinate (256-279) to hi-res column by dividing by 7.
;
1a36: 24 24 24 25+ div7_hi .bulk 242424252525252525252626262626262627272727272727
;
; Compute pixel mask for X coordinate (0-255).
;
1a4e: 01 02 04 08+ mod7_lo .bulk 0102040810204001020408102040010204081020400102040810204001020408
+ 1020400102040810204001020408102040010204081020400102040810204001
+ 0204081020400102040810204001020408102040010204081020400102040810
+ 2040010204081020400102040810204001020408102040010204081020400102
+ 0408102040010204081020400102040810204001020408102040010204081020
+ 4001020408102040010204081020400102040810204001020408102040010204
+ 0810204001020408102040010204081020400102040810204001020408102040
+ 0102040810204001020408102040010204081020400102040810204001020408
;
; Compute pixel mask for X coordinate (256-279).
;
1b4e: 10 20 40 01+ mod7_hi .bulk 102040010204081020400102040810204001020408102040
;
; The remaining items don't actually seem to be used.
;
1b66: d0 05 ad 00+ .junk 8
1b6e: 3a 20 53 59+ .str ‘: SYNTAX’
1b76: 8d .dd1 $8d
1b77: 3a 20 42 41+ .str ‘: BAD FORMAT’
1b83: 8d .dd1 $8d
1b84: 3a 20 4d 45+ .str ‘: MEMORY FULL’
1b91: 8d .dd1 $8d
1b92: 3a 20 42 41+ .str ‘: BAD RANGE’
1b9d: 8d .dd1 $8d
1b9e: 42 59 54 45+ .str ‘BYTES USED’
1ba8: 8d .dd1 $8d
1ba9: 42 59 54 45+ .str ‘BYTES REMAINING’
1bb8: 8d .dd1 $8d
1bb9: 41 4c 4c 20+ .str ‘ALL OR SOME?(A/S)?’
1bcb: 8d .dd1 $8d
1bcc: 3a 20 42 41+ .str ‘: BAD SLOT OR DRIVE ’